package com.wulis.config.mybatis.plus;

import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.wulis.common.model.enums.DeletedStateEnum;
import com.wulis.common.model.enums.FillFieldEnum;
import com.wulis.common.utils.AuthUserUtil;
import com.wulis.config.security.AuthUserDetails;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.HashSet;

/**
 * 元对象处理器(修改删除字段自动填充)
 * 
 * @author wuligao
 * @date 2020/5/25
 */
@Component
@Slf4j
public class MybatisPlusMetaObjectHandler implements MetaObjectHandler {
    
    /**
     * 添加方法自动填充
     */
    @Override
    public void insertFill(MetaObject metaObject) {
        // 获取当前登录对象
        AuthUserDetails authUserDetails = AuthUserUtil.getDetails();
        // 操作时间
        LocalDateTime optTime = LocalDateTime.now();
        // 获取到当前添加对象所有参数名
        String[] setterNames = metaObject.getSetterNames();
        // 将数组转成Set
        HashSet<String> setterNameSet = new HashSet<>(Arrays.asList(setterNames));
        // 需要添加默认值的字段筛选
        if (setterNameSet.contains(FillFieldEnum.CREATE_TIME.getProperty())) {
            // 添加时间默认值
            this.strictInsertFill(metaObject, FillFieldEnum.CREATE_TIME.getProperty(), LocalDateTime.class, optTime);
        }
        if (setterNameSet.contains(FillFieldEnum.UPDATE_TIME.getProperty())) {
            // 修改时间默认值
            this.strictInsertFill(metaObject, FillFieldEnum.UPDATE_TIME.getProperty(), LocalDateTime.class, optTime);
        }
        if (setterNameSet.contains(FillFieldEnum.CREATE_BY.getProperty())) {
            // 创建用户默认值
            this.strictInsertFill(metaObject,
                FillFieldEnum.CREATE_BY.getProperty(),
                Long.class,
                authUserDetails.getAccountId());
        }
        if (setterNameSet.contains(FillFieldEnum.UPDATE_BY.getProperty())) {
            // 修改用户默认值
            this.strictInsertFill(metaObject,
                FillFieldEnum.UPDATE_BY.getProperty(),
                Long.class,
                authUserDetails.getAccountId());
        }
        if (setterNameSet.contains(FillFieldEnum.DELETED.getProperty())) {
            // 填充逻辑删除字段（0：未删除）
            this.strictInsertFill(metaObject,
                FillFieldEnum.DELETED.getProperty(),
                Integer.class,
                DeletedStateEnum.NOT_DELETED.value());
        }
        
    }
    
    /**
     * 修改方法自动填充
     */
    @Override
    public void updateFill(MetaObject metaObject) {
        
        // 获取当前登录对象
        AuthUserDetails authUserDetails = AuthUserUtil.getDetails();
        
        // 获取到当前添加对象所有参数名
        String[] setterNames = metaObject.getSetterNames();
        // 将数组转成Set
        HashSet<String> setterNameSet = new HashSet<>(Arrays.asList(setterNames));
        
        // 需要添加默认值的字段筛选
        if (setterNameSet.contains(FillFieldEnum.UPDATE_TIME.getProperty())
            && judge(metaObject, FillFieldEnum.UPDATE_TIME.getProperty())) {
            // 添加时间默认值
            this.strictUpdateFill(metaObject,
                FillFieldEnum.UPDATE_TIME.getProperty(),
                LocalDateTime.class,
                LocalDateTime.now());
        }
        if (setterNameSet.contains(FillFieldEnum.UPDATE_BY.getProperty())
            && judge(metaObject, FillFieldEnum.UPDATE_BY.getProperty())) {
            // 添加时间默认值
            this.strictUpdateFill(metaObject,
                FillFieldEnum.UPDATE_BY.getProperty(),
                Long.class,
                authUserDetails.getAccountId());
        }
        
    }
    
    /**
     * 判断是否包含setter方法并且当前没有设置默认值
     * 
     * @param metaObject 元对象
     * @param setterName setter
     * @return boolean true:设置默认值 false:不需要默认值
     */
    private boolean judge(MetaObject metaObject, String setterName) {
        Object val = getFieldValByName(setterName, metaObject);
        return val == null;
    }
    
}
